Skip to content

Commit

Permalink
Make it a whole lot smaller
Browse files Browse the repository at this point in the history
  • Loading branch information
Slackadays committed Dec 5, 2022
1 parent ce24556 commit 79db7ce
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 9,073 deletions.
179 changes: 89 additions & 90 deletions src/clipboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <locale>
#include <iostream>
#include <fstream>
#include <unordered_map>

#if defined(_WIN32) || defined(_WIN64)
#include <io.h>
Expand All @@ -16,44 +17,59 @@
#include <unistd.h>
#endif

#define FMT_HEADER_ONLY
#include "fmt/format.h"

namespace fs = std::filesystem;

fs::path filepath;

enum class Action { Cut, Copy, Paste, PipeIn, PipeOut };
Action action;

std::unordered_map<Action, std::string_view> actions = {
{Action::Cut, "cut"},
{Action::Copy, "copy"},
{Action::Paste, "paste"},
{Action::PipeIn, "pipe in"},
{Action::PipeOut, "pipe out"},
};

std::unordered_map<Action, std::string_view> doing_action = {
{Action::Cut, "Cutting"},
{Action::Copy, "Copying"},
{Action::Paste, "Pasting"},
{Action::PipeIn, "Piping in"},
{Action::PipeOut, "Piping out"}
};

std::unordered_map<Action, std::string_view> did_action = {
{Action::Cut, "Cut"},
{Action::Copy, "Copied"},
{Action::Paste, "Pasted"},
{Action::PipeIn, "Piped in"},
{Action::PipeOut, "Piped out"}
};

std::vector<fs::path> items;

unsigned long files_success = 0;
unsigned long directories_success = 0;
unsigned long long bytes_success = 0;

std::string_view clipboard_version = "0.1.2";
constexpr std::string_view clipboard_version = "0.1.2";

std::string_view red = "\033[38;5;196m";
std::string_view green = "\033[38;5;40m";
std::string_view yellow = "\033[38;5;214m";
std::string_view orange = "\033[38;5;208m";
std::string_view blue = "\033[38;5;51m";
std::string_view pink = "\033[38;5;219m";
std::string_view bold = "\033[1m";
std::string_view blank = "\033[0m";
bool use_colors = true;

std::string_view copy_action = "copy";
std::string_view cut_action = "cut";
std::string_view paste_action = "paste";
std::unordered_map<std::string, std::string> colors = {
{"red", "\033[38;5;196m"},
{"green", "\033[38;5;40m"},
{"yellow", "\033[38;5;214m"},
{"blue", "\033[38;5;51m"},
{"orange", "\033[38;5;208m"},
{"pink", "\033[38;5;219m"},
{"bold", "\033[1m"},
{"blank", "\033[0m"}
};

std::string_view copied_action = "Copied";
std::string_view cut_past_action = "Cut";
std::string_view pasted_action = "Pasted";
std::string_view pipedin_action = "Piped in";
std::string_view pipedout_action = "Piped out";

std::string_view help_message = "{blue}โ–This is Clipboard {version}, the {cut}, {copy}, and {paste} system for the command line.{blank}\n"
std::string_view help_message = "{blue}โ–This is Clipboard %s, the {cut}, {copy}, and {paste} system for the command line.{blank}\n"
"{blue}{bold}โ–How To Use{blank}\n"
"{orange}โ–clipboard cut (item) [items]{blank}\n"
"{orange}โ–clipboard copy (item) [items]{blank}\n"
Expand All @@ -67,26 +83,34 @@ std::string_view help_message = "{blue}โ–This is Clipboard {version}, the {cut}
"{blue}โ–Copyright (C) 2022 Jackson Huff. Licensed under the GPLv3.{blank}\n"
"{blue}โ–This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.{blank}\n";
std::string_view no_valid_action_message = "{red}โ•ณ You did not specify a valid action, or you forgot to include one. {pink}Try using or adding {bold}cut, copy, or paste{blank}{pink} instead, like {bold}clipboard copy.{blank}\n";
std::string_view no_action_message = "{red}โ•ณ You did not specify an action. {pink}Try adding {bold}{cut}, {copy}, or {paste}{blank}{pink} to the end, like {bold}clipboard {copy}{blank}{pink}. If you need more help, try {bold}clipboard -h{blank}{pink} to show the help screen.{blank}\n";
std::string_view choose_action_items_message = "{red}โ•ณ You need to choose something to {action}.{pink} Try adding the items you want to {action} to the end, like {bold}clipboard {action} contacts.txt myprogram.cpp{blank}\n";
std::string_view fix_redirection_action_message = "{red}โ•ณ You can't use the {bold}{badaction}{blank}{red} action with redirection here. {pink}Try removing {bold}{badaction}{blank}{pink} or use {bold}{goodaction}{blank}{pink} instead, like {bold}clipboard {goodaction}{blank}{pink}.\n";
std::string_view copying_message = "{yellow}โ€ข Copying...{blank}\r";
std::string_view cutting_message = "{yellow}โ€ข Cutting...{blank}\r";
std::string_view pasting_message = "{yellow}โ€ข Pasting...{blank}\r";
std::string_view pipingin_message = "{yellow}โ€ข Piping in...{blank}\r";
std::string_view pipingout_message = "{yellow}โ€ข Piping out...{blank}\r";
std::string_view no_action_message = "{red}โ•ณ You did not specify an action. {pink}Try adding {bold}%s, %s, or %s{blank}{pink} to the end, like {bold}clipboard %s{blank}{pink}. If you need more help, try {bold}clipboard -h{blank}{pink} to show the help screen.{blank}\n";
std::string_view choose_action_items_message = "{red}โ•ณ You need to choose something to %s.{pink} Try adding the items you want to %s to the end, like {bold}clipboard %s contacts.txt myprogram.cpp{blank}\n";
std::string_view fix_redirection_action_message = "{red}โ•ณ You can't use the {bold}%s{blank}{red} action with redirection here. {pink}Try removing {bold}%s{blank}{pink} or use {bold}%s{blank}{pink} instead, like {bold}clipboard %s{blank}{pink}.\n";
std::string_view paste_success_message = "{green}โˆš Pasted successfully{blank}\n";
std::string_view paste_fail_message = "{red}โ•ณ Failed to paste{blank}\n";
std::string_view clipboard_failed_message = "{red}โ•ณ Clipboard couldn't {action} these items.{blank}\n";
std::string_view and_more_message = "{red}โ– ...and {num} more.{blank}\n";
std::string_view clipboard_failed_message = "{red}โ•ณ Clipboard couldn't %s these items.{blank}\n";
std::string_view and_more_message = "{red}โ– ...and %i more.{blank}\n";
std::string_view fix_problem_message = "{pink}โ– See if you have the needed permissions, or\n"
"โ– try double-checking the spelling of the files or what directory you're in.{blank}\n";
std::string_view pipe_success_message = "{green}โˆš {actioned} {num} bytes{blank}\n";
std::string_view one_item_success_message = "{green}โˆš {actioned} {item}{blank}\n";
std::string_view multiple_files_success_message = "{green}โˆš {actioned} {num} files{blank}\n";
std::string_view multiple_directories_success_message = "{green}โˆš {actioned} {num} directories{blank}\n";
std::string_view multiple_files_directories_success_message = "{green}โˆš {actioned} {numfiles} files and {numdirs} directories{blank}\n";
std::string_view internal_error_message = "{red}โ•ณ Internal error: {error}\nโ– This is probably a bug.{blank}\n";
std::string_view working_message = "{yellow}โ€ข %s...{blank}\r";
std::string_view pipe_success_message = "{green}โˆš %s %i bytes{blank}\n";
std::string_view one_item_success_message = "{green}โˆš %s %s{blank}\n";
std::string_view multiple_files_success_message = "{green}โˆš %s %i files{blank}\n";
std::string_view multiple_directories_success_message = "{green}โˆš %s %i directories{blank}\n";
std::string_view multiple_files_directories_success_message = "{green}โˆš %s %i files and %i directories{blank}\n";
std::string_view internal_error_message = "{red}โ•ณ Internal error: %s\nโ– This is probably a bug.{blank}\n";

std::string replaceColors(const std::string_view& str) {
std::string temp(str);
for (const auto& key : colors) {
std::string search = "{" + key.first + "}";
std::string replacement = use_colors ? key.second : "";
for (int i = 0; (i = temp.find(search, i)) != std::string::npos; i += replacement.length()) {
temp.replace(i, search.length(), replacement);
}
}
return temp;
}

void setLanguageES() {

Expand All @@ -104,14 +128,7 @@ void setupVariables(const int argc, char *argv[]) {
}

if (getenv("NO_COLOR") != nullptr) {
red = "";
green = "";
yellow = "";
blue = "";
pink = "";
orange = "";
bold = "";
blank = "";
use_colors = false;
}

if (std::locale("").name().substr(0, 3) == "es_") {
Expand All @@ -124,72 +141,68 @@ void setupVariables(const int argc, char *argv[]) {
void checkFlags(const int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
fmt::vprint(help_message, fmt::make_format_args(fmt::arg("blue", blue), fmt::arg("version", clipboard_version), fmt::arg("blank", blank), fmt::arg("bold", bold), fmt::arg("orange", orange), fmt::arg("cut", cut_action), fmt::arg("copy", copy_action), fmt::arg("paste", paste_action)));
printf(replaceColors(help_message).data(), clipboard_version.data());
exit(0);
}
}
if (argc >= 2) {
if (!strcmp(argv[1], "help")) {
fmt::vprint(help_message, fmt::make_format_args(fmt::arg("blue", blue), fmt::arg("version", clipboard_version), fmt::arg("blank", blank), fmt::arg("bold", bold), fmt::arg("orange", orange)));
printf(replaceColors(help_message).data(), clipboard_version.data());
exit(0);
}
}
}

void setupAction(const int argc, char *argv[]) {
if (argc >= 2) {
if (!strncmp(argv[1], cut_action.data(), 2)) {
if (!strncmp(argv[1], actions[Action::Cut].data(), 2)) {
if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
action = Action::Cut;
} else {
fmt::vprint(stderr, fix_redirection_action_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("bold", bold), fmt::arg("badaction", cut_action), fmt::arg("goodaction", copy_action), fmt::arg("blank", blank), fmt::arg("pink", pink)));
fprintf(stderr, replaceColors(fix_redirection_action_message).data(), actions[action].data(), actions[Action::Copy].data());
exit(1);
}
} else if (!strncmp(argv[1], copy_action.data(), 2)) {
} else if (!strncmp(argv[1], actions[Action::Copy].data(), 2)) {
if (isatty(fileno(stdin))) {
action = Action::Copy;
} else if (!isatty(fileno(stdin))) {
action = Action::PipeIn;
} else {
fmt::vprint(stderr, fix_redirection_action_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("bold", bold), fmt::arg("badaction", copy_action), fmt::arg("goodaction", paste_action), fmt::arg("blank", blank), fmt::arg("pink", pink)));
fprintf(stderr, replaceColors(fix_redirection_action_message).data(), actions[action].data(), actions[Action::Paste].data());
exit(1);
}
} else if (!strncmp(argv[1], paste_action.data(), 1)) {
} else if (!strncmp(argv[1], actions[Action::Paste].data(), 1)) {
if (isatty(fileno(stdin)) && isatty(fileno(stdout))) {
action = Action::Paste;
} else if (!isatty(fileno(stdout))) {
action = Action::PipeOut;
} else {
fmt::vprint(stderr, fix_redirection_action_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("bold", bold), fmt::arg("badaction", paste_action), fmt::arg("goodaction", copy_action), fmt::arg("blank", blank), fmt::arg("pink", pink)));
fprintf(stderr, replaceColors(fix_redirection_action_message).data(), actions[action].data(), actions[Action::Copy].data());
exit(1);
}
} else {
fmt::vprint(no_valid_action_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("pink", pink), fmt::arg("bold", bold), fmt::arg("blank", blank)));
printf("%s", replaceColors(no_valid_action_message).data());
exit(1);
}
} else if (!isatty(fileno(stdin))) {
action = Action::PipeIn;
} else if (!isatty(fileno(stdout))) {
action = Action::PipeOut;
} else {
fmt::vprint(no_action_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("pink", pink), fmt::arg("bold", bold), fmt::arg("blank", blank), fmt::arg("cut", cut_action), fmt::arg("copy", copy_action), fmt::arg("paste", paste_action)));
printf(replaceColors(no_action_message).data(), actions[Action::Cut].data(), actions[Action::Copy].data(), actions[Action::Paste].data(), actions[Action::Copy].data());
exit(1);
}
if (action == Action::PipeIn || action == Action::PipeOut) {
if (argc >= 3) {
fmt::vprint(stderr, "{red}โ•ณ You can't specify items when you use redirection. {pink}Try removing the items that come after {bold}clipboard [action].\n", fmt::make_format_args(fmt::arg("red", red), fmt::arg("pink", pink), fmt::arg("bold", bold)));
fprintf(stderr, "%s", replaceColors("{red}โ•ณ You can't specify items when you use redirection. {pink}Try removing the items that come after {bold}clipboard [action].\n").data());
exit(1);
}
}
}

void checkForNoItems() {
if ((action == Action::Cut || action == Action::Copy) && items.size() < 1) {
if (action == Action::Copy) {
fmt::vprint(choose_action_items_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("action", copy_action), fmt::arg("pink", pink), fmt::arg("bold", bold), fmt::arg("blank", blank)));
} else if (action == Action::Cut) {
fmt::vprint(choose_action_items_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("action", cut_action), fmt::arg("pink", pink), fmt::arg("bold", bold), fmt::arg("blank", blank)));
}
printf(replaceColors(choose_action_items_message).data(), actions[action].data(), actions[action].data(), actions[action].data());
exit(1);
}
}
Expand All @@ -206,21 +219,6 @@ void setupTempDirectory() {
}
}

void setupIndicator() {
if (action == Action::Copy) {
fmt::vprint(copying_message, fmt::make_format_args(fmt::arg("yellow", yellow), fmt::arg("blank", blank)));
} else if (action == Action::Cut) {
fmt::vprint(cutting_message, fmt::make_format_args(fmt::arg("yellow", yellow), fmt::arg("blank", blank)));
} else if (action == Action::Paste) {
fmt::vprint(pasting_message, fmt::make_format_args(fmt::arg("yellow", yellow), fmt::arg("blank", blank)));
} else if (action == Action::PipeIn) {
fmt::vprint(stderr, pipingin_message, fmt::make_format_args(fmt::arg("yellow", yellow), fmt::arg("blank", blank)));
} else if (action == Action::PipeOut) {
fmt::vprint(stderr, pipingout_message, fmt::make_format_args(fmt::arg("yellow", yellow), fmt::arg("blank", blank)));
}
fflush(stdout);
}

void performAction() {
std::vector<std::pair<fs::path, fs::filesystem_error>> failedItems;
fs::copy_options opts = fs::copy_options::recursive | fs::copy_options::copy_symlinks | fs::copy_options::overwrite_existing;
Expand Down Expand Up @@ -262,9 +260,9 @@ void performAction() {
} else if (action == Action::Paste) {
try {
fs::copy(filepath, fs::current_path(), opts);
fmt::vprint(paste_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("blank", blank)));
printf("%s", replaceColors(paste_success_message).data());
} catch (const fs::filesystem_error& e) {
fmt::vprint(paste_fail_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("blank", blank)));
printf("%s", replaceColors(paste_fail_message).data());
}
} else if (action == Action::PipeIn) {
std::ofstream file(filepath / "clipboard.txt");
Expand All @@ -284,14 +282,14 @@ void performAction() {
file.close();
}
if (failedItems.size() > 0) {
fmt::vprint(clipboard_failed_message, fmt::make_format_args(fmt::arg("action", action == Action::Copy ? copy_action : cut_action), fmt::arg("red", red), fmt::arg("blank", blank)));
printf(replaceColors(clipboard_failed_message).data(), actions[action].data());
for (int i = 0; i < std::min(5, int(failedItems.size())); i++) {
fmt::vprint("{red}โ– {item}: {error}{blank}", fmt::make_format_args(fmt::arg("red", red), fmt::arg("error", failedItems.at(i).first.string()), fmt::arg("error", failedItems.at(i).second.code().message()), fmt::arg("blank", blank)));
printf("{red}โ– %s: %s{blank}", failedItems.at(i).first.string().data(), failedItems.at(i).second.code().message().data());
if (i == 4 && failedItems.size() > 5) {
fmt::vprint(and_more_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("num", int(failedItems.size() - 5)), fmt::arg("blank", blank)));
printf(replaceColors(and_more_message).data(), int(failedItems.size() - 5));
}
}
fmt::vprint(fix_problem_message, fmt::make_format_args(fmt::arg("pink", pink), fmt::arg("blank", blank)));
printf("%s", replaceColors(fix_problem_message).data());
}
for (const auto& f : failedItems) {
items.erase(std::remove(items.begin(), items.end(), f.first), items.end());
Expand All @@ -300,18 +298,18 @@ void performAction() {

void showSuccesses() {
if (bytes_success > 0) {
fmt::vprint(stderr, pipe_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("num", bytes_success), fmt::arg("blank", blank), fmt::arg("actioned", action == Action::PipeIn ? pipedin_action : pipedout_action)));
fprintf(stderr, replaceColors(pipe_success_message).data(), did_action[action].data(), bytes_success);
return;
}
if ((files_success == 1 && directories_success == 0) || (files_success == 0 && directories_success == 1)) {
fmt::vprint(one_item_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("item", items.at(0).string()), fmt::arg("blank", blank), fmt::arg("actioned", action == Action::Copy ? copied_action : cut_past_action)));
printf(replaceColors(one_item_success_message).data(), items.at(0).string().data(), did_action[action].data());
} else {
if ((files_success > 1) && (directories_success == 0)) {
fmt::vprint(multiple_files_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("num", files_success), fmt::arg("blank", blank), fmt::arg("actioned", action == Action::Copy ? copied_action : cut_past_action)));
printf(replaceColors(multiple_files_success_message).data(), did_action[action].data(), files_success);
} else if ((files_success == 0) && (directories_success > 1)) {
fmt::vprint(multiple_directories_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("num", directories_success), fmt::arg("blank", blank), fmt::arg("actioned", action == Action::Copy ? copied_action : cut_past_action)));
printf(replaceColors(multiple_directories_success_message).data(), did_action[action].data(), directories_success);
} else if ((files_success >= 1) && (directories_success >= 1)) {
fmt::vprint(multiple_files_directories_success_message, fmt::make_format_args(fmt::arg("green", green), fmt::arg("numfiles", files_success), fmt::arg("numdirs", directories_success), fmt::arg("blank", blank), fmt::arg("actioned", action == Action::Copy ? copied_action : cut_past_action)));
printf(replaceColors(multiple_files_directories_success_message).data(), did_action[action].data(), files_success, directories_success);
}
}
}
Expand All @@ -326,15 +324,16 @@ int main(int argc, char *argv[]) {

checkForNoItems();

setupIndicator();
printf(replaceColors(working_message).data(), doing_action[action].data()); //action indicator
fflush(stdout);

setupTempDirectory();

performAction();

showSuccesses();
} catch (const std::exception& e) {
fmt::vprint(stderr, internal_error_message, fmt::make_format_args(fmt::arg("red", red), fmt::arg("error", e.what()), fmt::arg("blank", blank)));
fprintf(stderr, replaceColors(internal_error_message).data(), e.what());
exit(1);
}
return 0;
Expand Down
Loading

0 comments on commit 79db7ce

Please sign in to comment.